package com.twu.biblioteca;

import com.twu.biblioteca.common.MainMenu;
import com.twu.biblioteca.entity.Account;
import com.twu.biblioteca.entity.Book;
import com.twu.biblioteca.entity.CheckBookInfo;
import com.twu.biblioteca.entity.User;
import com.twu.biblioteca.repository.AccountRepository;
import com.twu.biblioteca.repository.CheckoutRepository;
import com.twu.biblioteca.repository.UserRepository;

import java.util.Scanner;

public class BibliotecaApp {
    static BookList bookList = new BookList();
    static MovieList movieList = new MovieList();
    private static AccountRepository accountRepository = new AccountRepository();
    private static Account currentAccount;
    private static CheckoutRepository checkoutRepository = new CheckoutRepository();
    private static User currentUser;
    private static UserRepository userRepository = new UserRepository();

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        if (prepareLogin(scanner, new LoginService())) return;
        if(currentUser.isCustomer()) {
            customerOperate(scanner);
        }
        else if (currentUser.IsLiberian()) {
            librarianOperate(scanner);
        }
    }

    private static void librarianOperate(Scanner scanner) {
        printMessage("please enter the account library number to get the user check out information :\n");
        String libraryNum = scanner.nextLine();
        CheckBookInfo checkoutInfo = getCheckoutInfo(libraryNum);

        if(checkoutInfo == null)  { printMessage("no valid checkout info!\n");return;}
        printMessage(checkoutInfo.toString());

        returnbookOperate(scanner, libraryNum);
    }

    private static void returnbookOperate(Scanner scanner, String libraryNum) {
        String input;
        printMessage("return book ? (Y/N) :\n");
        input = scanner.nextLine();
        if("Y".equals(input)){
            printMessage("please input the book to return :\n");
            if(returnBook(libraryNum, scanner.nextLine())){
                printMessage("return success!");
            }
            else{
                printMessage("invalid account or book!");
            }
        }
    }

    private static void customerOperate(Scanner scanner) {
        String input;
        printMessage("Main Menu:\tQuit-------0\t\tBookList--------1\t\tMovieList-------2\n");
        printMessage("Please select(0/1/2):\n");

        input = scanner.nextLine();
        while (true) {
            if (input.isEmpty()) printMessage("Select a valid option!\n");
            else {
                if (MainMenu.Quit.ordinal() == Integer.parseInt(input)) break;
                printMessage(getList(Integer.parseInt(input)));
                if (Integer.parseInt(input) == (MainMenu.BookList.ordinal())) {
                    bookOperation(scanner);
                    break;
                }
                if (Integer.parseInt(input) == (MainMenu.MovieList.ordinal())) {
                    movieOperator(scanner);
                    break;
                }
            }
            input = scanner.nextLine();
        }
    }

    private static boolean prepareLogin(Scanner scanner, LoginService loginService) {
        printMessage("please login:\n");
        printMessage("LibraryNumber : ");
        String libraryNumber = scanner.nextLine();
        printMessage("password :");
        String password = scanner.nextLine();

        boolean login = login(libraryNumber, password);

        int loginNumber = 1;
        int MAX_COUNT = 3;
        while(!login && loginNumber < MAX_COUNT){
            printMessage("wrong library number or password!\n");
            printMessage("LibraryNumber : ");
            libraryNumber = scanner.nextLine();
            printMessage("password :");
            password = scanner.nextLine();
            login = login(libraryNumber, password);
            loginNumber++;
        }
        if(loginNumber == MAX_COUNT)
            return true;

        printUserInfo(login);
        printMessage(getWelcomeMessage());
        return false;
    }

    public static void printUserInfo(boolean login) {
        printMessage("------------------------------User Information--------------------------------\n\n");
        printMessage(getUser(login).toString());
        printMessage("\n");
    }

    private static void movieOperator(Scanner scanner) {
        printMessage("Please input the name of the movie you want to checkout:\n");
        String name = scanner.nextLine();
        printMessage(checkoutMovie(name));
    }

    private static void bookOperation(Scanner scanner) {
        printMessage("checkout/return book :  checkout---------0,return---------1\n");
        String input = scanner.nextLine();
        String name;
        if(0 == Integer.parseInt(input))
        {
            printMessage("Please input the name of the book you want to checkout:\n");
            name = scanner.nextLine();
            printMessage(checkoutBook(name));
            input = checkoutInfo(scanner);
        }
        else{
            if(1 == Integer.parseInt(input))
            {
                printMessage("Please input the name of the book you want to return:\n");
                name = scanner.nextLine();
                printMessage(returnBook(name));
            }
        }
    }

    private static String checkoutInfo(Scanner scanner) {
        String input;
        printMessage("See the checkout message?(Y/N):\n");
        input = scanner.nextLine();
        if(input.equals("Y")){
            printMessage(getCheckoutInfo(currentAccount.getLibraryNumber()).toString());
        }
        return input;
    }

    private static String checkoutMovie(String name) {
        String message = "Thank you! Enjoy the movie.\n";
        if(!movieList.containAndCheck(name))
            message = "That movie is not available.\n";

        return message;
    }

    public static void printMessage(String message) {
        System.out.print(message);
    }

    public static String getWelcomeMessage() {
        return  "-----------------------------------------------------------------------------\n" +
                "*******************Welcome to The Bangalore Public Library*******************\n"+
                "-----------------------------------------------------------------------------\n"
                ;
    }
    public static String getList(int input) {
        switch (input){
            case 0: return null;
            case 1: return bookList.toString();
            case 2: return movieList.toString();
            default: return "Select a valid option!\n";
        }
    }

    public static String checkoutBook(String input) {

        String message = "Thank you! Enjoy the book.\n";
        if(bookList.containAndCheck(input)){
            setCheckoutInfo(input,currentAccount.getLibraryNumber());
        }
        else
        {
            message = "That book is not available.\n";
        }

        return message;
    }

    private static void setCheckoutInfo(String name, String libraryNumber) {
        Book book = bookList.getBook(name);
        checkoutRepository.setCheckoutInfo(new CheckBookInfo(book, libraryNumber));
    }

    public static String returnBook(String bookName) {

        String message = "Thank you for returning the book.\n";
        if(bookList.belongAndReturn(bookName)){
            checkoutRepository.removeCheckoutInfo(currentAccount.getLibraryNumber(), bookName);
        }
        else {
            message = "That is not a valid book to return.\n";
        }
        return message;
    }

    public static boolean returnBook(String libraryNumber, String bookName) {

        if(bookList.belongAndReturn(bookName)){
            checkoutRepository.removeCheckoutInfo(libraryNumber,bookName);
            return true;
        }
        else {
            return false;
        }
    }

    public static boolean login(String libraryNumber, String password) {
        Account account = new Account(libraryNumber,password);
        currentAccount = account;
        return accountRepository.contains(account);
    }

    public static User getUser(boolean isContain) {
        if(isContain){
            currentUser = userRepository.getUserInfo(currentAccount.getLibraryNumber());
        }
        return currentUser;
    }

    public static CheckBookInfo getCheckoutInfo(String libraryNumber) {
        return checkoutRepository.getCheckoutInfo(libraryNumber);
    }
}
